1. 作用域
var
:具有函数作用域或全局作用域。在块(如if
语句或for
循环)内声明的var
变量实际上会被提升到函数作用域的顶部。let
和const
:具有块级作用域。它们只在声明它们的块内有效,例如在if
语句、for
循环或任何其他块{}
中。
2. 重复声明
var
:在同一作用域内可以重复声明同一个变量。let
和const
:不允许在同一作用域内重复声明。
3. 变量提升
var
:变量会被提升到其所在函数或全局作用域的顶部,但是初始化(赋值)不会提升。let
和const
:不会提升到块的顶部,而是提升到块的开始。在声明之前访问它们会导致ReferenceError
,这个区域被称为“暂时性死区”。
// var
console.log(a); // undefined
var a = 10;
// let
console.log(b); // Cannot access 'b' before initialization
let b = 10;
// const
console.log(c); // Cannot access 'c' before initialization
const c = 10;
4. 赋值和修改
var
和let
:可以被重新赋值和修改。const
:一旦声明并初始化后,其值不能被改变(对于基本数据类型)。如果const
用于对象或数组,可以修改其属性或元素,但不能重新赋值。
5. 总结
let 与 var 的区别
let 不存在变量提升
var 存在 变量提升 现象,即变量可以在声明之前使用,值为 undefined。let 或 const 所声明的变量一定要在声明后使用,否则报错。
let 不允许重复声明
let 不允许在相同作用域内,重复声明同一个变量,重复声明报错。var 重复声明会覆盖或忽略。const 声明的常量,也与 let 一样不可重复声明。
let 不绑定全局作用域
当在全局作用域中使用 var 声明的时候,会创建一个新的全局变量作为全局对象的属性。然而 let 和 const 不会。
let 存在暂时性死区现象
在 let 和 const 声明变量之前,只要变量在还没有声明完成前使用,就会报错,都属于该变量的 暂时性死区。即,let 和 const 声明的变量不会被提升到作用域顶部,如果在声明之前访问这些变量,会导致报错。let 和 const 声明的变量会放在 TDZ 暂时性死区里面,访问暂时性死区的变量就会报错,且检测报错发生在词法解析(AST词法解析树)阶段,而不是在代码执行阶段。
let 会产生块级作用域
let 或 const 只在声明所在的块级作用域内有效,即,块级作用域中有效。块级作用域的出现,实际上使得获得广泛应用的匿名立即执行函数表达式(匿名 IIFE)不再必要了。
let 与 const 的区别
const 声明一个只读的常量。一旦声明,常量的值就不能改变。
const 声明的变量不得改变值,这意味着,const 一旦声明变量,就必须立即初始化,不能留到以后赋值。对于 const 来说,只声明不赋值,就会报错。const 声明不允许修改绑定,但允许修改值。这意味着当用 const 声明对象时,可以修改对象的属性值,只是不能修改对象在栈中的引用地址。
const 简单类型一旦声明就不能再更改,复杂类型(数组、对象等)指针指向的地址不能更改,内部数据可以更改。